<?php


namespace App\Services;

use Elasticsearch\ClientBuilder;

class ElasticSearchService
{
    private static $_instance;

    //构造函数和克隆函数都声明为私有的
    private function __construct()
    {
        //$this->_db=mysql_connect();
    }

    private function __clone()
    {
        //实现
    }

    //访问实例的公共静态方法
    public static function getInstance()
    {
        if (!(self::$_instance instanceof self)) {
            return self::$_instance = new self();
        } else {
            return self::$_instance;
        }
    }

    /**
     * @Notes:
     * @Author:Planb,
     * @Date: 2022/10/14,
     * @Time: 17:48,
     * 创建拼音分词
     */
    public function createIndex($index, $title)
    {
        $client = ClientBuilder::create()->setHosts(['49.234.48.38:9200'])->build();
        $param = [
            'index' => $index,
            'body' => [
                'settings' => [
                    'analysis' => [
                        'analyzer' => [
                            'pinyin_analyzer' => [
                                'type' => 'custom',
                                'tokenizer' => 'my_pinyin'
                            ]
                        ],
                        'tokenizer' => [
                            'my_pinyin' => [
                                'type' => 'pinyin',
                                //keep_separate_fifirst_letter：启用该选项时，将保留第一个字母分开，例如：刘德华> l，d，h，默认：假的，注意：查询结果也许是太模糊，由于长期过频
                                'keep_separate_first_letter' => false,
                                //keep_full_pinyin：当启用该选项，例如：刘德华> [ liu，de，hua]，默认值：true
                                'keep_full_pinyin' => true,
                                //keep_original：当启用此选项时，也会保留原始输入，默认值：false
                                'keep_original' => false,
                                //limit_fifirst_letter_length：设置fifirst_letter结果的最大长度，默认值：16
                                'limit_first_letter_length' => 16,
                                //lowercase：小写非中文字母，默认值：true
                                'lowercase' => true,
                                //remove_duplicated_term：当启用此选项时，将删除重复项以保存索引，例如：de的> de，默认值： false，注意：位置相关查询可能受影响
                                'remove_duplicated_term' => true,
                                "ignore_pinyin_offset" => false,
                            ]
                        ]
                    ]
                ],
                'mappings' => [
                    '_source' => [
                        'enabled' => true
                    ],
                    'properties' => [
                        $title => [
                            'type' => 'text',
                            'analyzer' => 'pinyin_analyzer',
                            'search_analyzer' => 'pinyin_analyzer'
                        ]
                    ]
                ]
            ]
        ];

        return $client->indices()->create($param);
    }

    public function createDocument($index, $id, $data)
    {

        $client = ClientBuilder::create()->setHosts(['49.234.48.38:9200'])->build();
        $params = [
            'index' => $index,
            'type' => '_doc',
            'id' => $id,
            'body' => $data
        ];
        return $response = $client->index($params);

    }

    /**
     * 搜索+高亮显示
     * @param $index
     * @param $limit
     * @param $offset
     * @param $field
     * @param $search
     * @return bool
     */

    public function searchDocument($index, $limit, $offset, $field, $search)
    {

        $client = ClientBuilder::create()->setHosts(['49.234.48.38:9200'])->build();
        $params = [
            'index' => $index,
            'size' => $limit,
            'from' => $offset,
            'body' => [
                'query' => [
                    'bool' => [
                        'must' => [
                            'match' => [
                                $field => $search
                            ]
                        ]
                    ]
                ],
                "highlight" => [
                    'fields' => [
                        "$field" => [
                            "pre_tags" => [
                                "<span style='color: #ff0000'>"
                            ],
                            "post_tags" => [
                                "</span>"
                            ]
                        ]
                    ]
                ]
            ]
        ];
        $response = $client->search($params);
        if (!$response['hits']['hits']) {
            return false;
        }
        foreach ($response['hits']['hits'] as $v) {
            $v['_source'][$field] = $v['highlight'][$field][0];
            $res[] = $v['_source'];
        }

        $result['houseList'] = $res;
        $result['count'] = $response['hits']['total']['value'];
        if ($result) {
            return $result;
        } else {
            return false;
        }
    }


    /**
     * 删除文档
     */
    public function deleteDocument($index, $id)
    {
        $client = ClientBuilder::create()->setHosts(['49.234.48.38:9200'])->build();
        $params = [
            'index' => $index,
            'type' => '_doc',
            'id' => $id
        ];

        $response = $client->delete($params);

    }

    /**
     * @Notes:
     * @Author: 遇见
     * @Date: 2022/11/16
     * @Time: 19:30
     * 创建普通索引
     */
    public function createOrdinary($index, $text)
    {
        $client = ClientBuilder::create()->build();
        $param = $params = [
            'index' => $index,
            'body' => [
                'id' => $text['id'],
                'uid' => $text['uid'],
                'house_name' => $text['house_name'],
                'house_type' => $text['house_type'],
                'house_region' => $text['house_region'],
                'house_product' => $text['house_product'],
                'house_budget' => $text['house_budget'],
                'house_rent_and_purchase' => $text['house_rent_and_purchase'],
                'house_title' => $text['house_title'],
                'house_text' => $text['house_text'],
                'house_end_time' => $text['house_end_time'],
                'house_region_list' => $text['house_region_list'],
                'house_city' => $text['house_city'],
                'house_price_type' => $text['house_price_type'],
                'created_at' => $text['created_at'],
                'updated_at' => $text['updated_at'],
                'deleted_at' => $text['deleted_at'],
            ]
        ];
        $client->index($param);
    }

    /**
     * @Notes:
     * @Author: 遇见
     * @Date: 2022/11/17
     * @Time: 9:56
     * @param $index
     * @param $region
     * @param $city
     * @param $type
     * @param $count
     * @param $offset
     * @return array
     * 普通搜索
     */
    public function searchEs($index, $region, $city, $type, $count, $offset)
    {
        $client = ClientBuilder::create()->build();
        if (!empty($region) && empty($city) && !empty($type)) {//搜索市 + 类型
            $params = [
                'index' => $index,
                'body' => [
                    'query' => [
                        "bool" => [
                            "should" => [
                                "match" => [
                                    config("els.type") => $type
                                ],
                                'term' => [config('els.city') . ".keyword" => $region]
                            ]
                        ]
                    ]

                ]
            ];
            $data = [];
            $response = $client->search($params);
            foreach ($response['hits']['hits'] as $v) {
                $data[]['id'] = $v['_source']['id'];
            }
            return $data;

        }
        if (!empty($region) && empty($city) && empty($type)) {//搜索市
            $params = [
                'index' => $index,
                'body' => [
                    'query' => [
                        "bool" => [
                            "should" => [
                                "term" => [
                                    config("els.city") . ".keyword" => $region
                                ]
                            ]
                        ]
                    ]

                ]
            ];
            $data = [];
            $response = $client->search($params);
            foreach ($response['hits']['hits'] as $v) {
                $data[]['id'] = $v['_source']['id'];
            }
            return $data;

        }
        if (!empty($city) && !empty($region) && empty($type)) {//搜索市区
            $params = [
                'index' => $index,

                'body' => [
                    'query' => [
                        'bool' => [
                            'must' => [//多条件搜索 should 或者 must 并且
                                ['term' => [config('els.city') . ".keyword" => $region]],
                                ['term' => [config('els.region') . ".keyword" => $city]],
                            ]
                        ]
                    ]
                ]
            ];
            $data = [];
            $response = $client->search($params);
            foreach ($response['hits']['hits'] as $v) {
                $data[]['id'] = $v['_source']['id'];
            }
            return $data;
        }
        if (!empty($city) && !empty($type) && !empty($region)) {//搜索市区+类型
            $params = [
                'index' => $index,
                'body' => [
                    'query' => [
                        'bool' => [
                            'must' => [//多条件搜索 should 或者 must 并且
                                ['term' => [config('els.city') . ".keyword" => $region]],
                                ['term' => [config('els.region') . ".keyword" => $city]],
                                ['match' => [config('els.type') => $type]],
                            ]
                        ]
                    ]
                ]
            ];
            $data = [];
            $response = $client->search($params);
            foreach ($response['hits']['hits'] as $v) {
                $data[]['id'] = $v['_source']['id'];
            }
            return $data;
        }

    }
}
